import { defineStore } from 'pinia'
import { changeCartItemNum } from '@/api/cart.js'
// Store 是使用 defineStore() 定义的，并且它需要一个唯一名称(id)，作为第一个参数传递，参数二是配置对象
// 命名规则要以 use 开头，例如 useUser、useCart
const useCartStore = defineStore('cartId', {
  // 一、state 这里设置状态管理的变量
  state: () => {
    return {
      // 1. 用于存储购物车列表数据的数组，每一个对象代表一个商品
      // 对象中包括的属性：当前列表项对应的 id、是否被选中 checked、购买数量 count、商品图片 image、商品标题 title、价格 price、库存 stock、商品编号 productId
      cartList: []
    }
  },
  // 二、状态需要被多次修改，而且每次修改都需被访问到，可以使用计算属性 getters 来设置
  // 建议使用箭头函数，通过参数 state 获取状态，依据 state 中状态的类型，会自动返回对应的类型
  // 可以通过 this 访问其他的 getter
  getters: {
    // 1. 获取被选中的商品选项，存放在一个数组中
    checkedItem: (state) => state.cartList.filter(item => item.checked === true),
    // 2. 基于被选中的商品选项，计算总价格，toFixed(2) 保留两位小数
    /*
    reduce 为数组中的每一个元素一次执行参数一的回调函数，第二个参数是设置回调函数第一个参数 sum 的初始值；
    回调函数有四个参数：
    参数一：prev 必需，上一次调用回调函数的返回值，或者是 reduce 第二个参数设置的初始值；
    参数二：cur 必需，数组中当前被处理的元素；
    参数三：index 可选，当前元素在数组中的索引；
    参数四：arr 可选，调用 reduce 的数组；
    */
    totalPrice: (state) => state.checkedItem.reduce((sum, item) => sum + item.price * item.count, 0).toFixed(2),
    // 3. 获取全选按钮的状态，被选中的个数与购物车列表数量一致时，为 true
    checkedAll: (state) => state.cartList.length === state.checkedItem.length
  },
  // 三、actions 定义方法对 state 中的状态进行处理
  actions: {
    // 1. 添加商品对象 item，item 对象中具体的信息参考 cartList 说明
    setCartList (item) {
      this.cartList.push(item)
    },
    // 2. 清除购物车列表数据
    clearCartList () {
      this.cartList = []
    },
    // 3. 修改购物车列表中对应商品的选中状态，newChecked 传入的就是选中状态，id 是用来判断修改哪一个商品的状态
    changeChecked (newChecked, id) {
      this.cartList.find(item => item.id === id).checked = newChecked
    },
    // 4. 修改购物车列表商品的购买数量，同时发送异步请求，将修改后的数量同步到服务器上
    // newCount 传入的就是修改之后的商品购买数量，id 是用来判断修改哪一个商品的状态
    async changeCount (newCount, id) {
      // 4.1 根据 id 找到对应的商品列表项，修改其购买数量的状态
      this.cartList.find(item => item.id === id).count = newCount
      // 4.2 发送请求，将商品修改后的商品购买数量提交给服务器
      const { data } = await changeCartItemNum({
        id,
        number: newCount
      })
      // 请求失败后的处理
      if (data.status !== 200) { alert('购买数量修改失败') }
    },
    // 5. 点击全选按钮，设置每一个商品选项的选中状态，与全选按钮的状态一致
    changeAll (newChecked) {
      this.cartList.forEach(item => (item.checked = newChecked))
    }
  }
})

export default useCartStore
